home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / Directory source / window.c < prev   
Encoding:
C/C++ Source or Header  |  1988-10-28  |  8.7 KB  |  582 lines  |  [TEXT/KAHL]

  1. /*    window.c
  2.  *
  3.  *    Generic window management routines.
  4.  *
  5.  *
  6.  *    The window management routines to create and distroy drawing windows and their data
  7.  *    structures, to redraw windows, and to append lines to the window line buffer, as well
  8.  *    to managing scrolling and such.  This is the total of all the routines to manage windows.
  9.  *    This also contains the code to manage the project window as such.
  10.  */
  11.  
  12.  
  13. #include <stdio.h>
  14. #include "struct.h"
  15. #include "res.h"
  16. #include "error.h"
  17.  
  18.  
  19.  
  20.  
  21. /*    GLOBALS
  22.  *
  23.  *        The globals used for the window structure.
  24.  */
  25.  
  26.  
  27. struct WindDraw *drawList;
  28. static struct WindDraw *whichScroll;            /* What window is being scrolled? */
  29. Rect openSize;
  30. extern unsigned char MultiWidget;                /* State flags */
  31.  
  32.  
  33.  
  34.  
  35. /*    CODE
  36.  *
  37.  *        The different routines
  38.  */
  39.  
  40.  
  41. /*
  42.  *                        Basic allocation/deallocation of windows
  43.  */
  44.  
  45.  
  46.  
  47. /*    AllocWind
  48.  *
  49.  *    This allocs a new window.  WARNING:  Errors are returned using the 'Throw' mechanism.
  50.  */
  51.  
  52. struct WindDraw *AllocWind()
  53. {
  54.     int i;
  55.     
  56.     for (i = 0; i < MAXWINDOWS; i++) if (drawList[i].inuse == 0) break;
  57.     if (i == MAXWINDOWS) Throw(OUTWINDOWS);
  58.  
  59.     drawList[i].inuse = 1;
  60.     openSize.top = 38 + i * 20;
  61.     openSize.left = 30 - i * 3;
  62.     openSize.right = -i * 3;
  63.     openSize.bottom = - 10;
  64.     if (MultiWidget) openSize.right -= 75;
  65.     return &(drawList[i]);
  66. }
  67.  
  68.  
  69. /*    FreeWind
  70.  *
  71.  *    This frees a window.  Only do this AFTER disposing of the window
  72.  */
  73.  
  74. FreeWind(w)
  75. struct WindDraw *w;
  76. {
  77.     w->inuse = 0;
  78. }
  79.  
  80.  
  81.  
  82.  
  83. /*
  84.  *                        Basic window math
  85.  */
  86.  
  87.  
  88. /*    CalcScroll
  89.  *
  90.  *    Given a window, this computes where the scroll bars are to go.
  91.  */
  92.  
  93. CalcScroll(w,x,y)
  94. WindowPtr w;
  95. Rect *x,*y;
  96. {
  97.     Rect r;
  98.     
  99.     r = w->portRect;
  100.     x->top = r.bottom - 15;
  101.     x->bottom = r.bottom + 1;
  102.     x->right = r.right - 14;
  103.     x->left = -1;
  104.     
  105.     y->top = -1;
  106.     y->bottom = r.bottom - 14;
  107.     y->left = r.right - 15;
  108.     y->right = r.right + 1;
  109. }
  110.  
  111.  
  112. /*    CalcClip
  113.  *
  114.  *    Calculate the clip area of the window (where to draw, which doesn't include scroll
  115.  *    bars
  116.  */
  117.  
  118. CalcClip(w,c)
  119. WindowPtr w;
  120. Rect *c;
  121. {
  122.     Rect r;
  123.  
  124.     r = w->portRect;
  125.     c->top = r.top;
  126.     c->left = r.left;
  127.     c->right = r.right - 15;
  128.     c->bottom = r.bottom - 15;
  129. }
  130.  
  131.  
  132. /*
  133.  *                        Window management
  134.  */
  135.  
  136.  
  137. /*    NewPlan
  138.  *
  139.  *    Open a new window
  140.  */
  141.  
  142. struct WindDraw *NewPlan(name)
  143. short name;                                /* vRefNum of this object */
  144. {
  145.     int i;
  146.     struct WindDraw *w;
  147.     short step;
  148.     GrafPtr foo;
  149.     Rect r;
  150.     Rect s;
  151.     int t;
  152.  
  153.     /*
  154.      *    Step 1:  Prepare for disaster
  155.      */
  156.     
  157.     step = 1;
  158.     if (i = Catch()) {
  159.     
  160.         /*
  161.          *    According to the step number, do the appropriate shutting down
  162.          */
  163.  
  164.         switch (step) {
  165.             case 2:
  166.                 CloseWindow(w);
  167.                 FreeWind(w);
  168.             case 1:
  169.                 break;
  170.         }
  171.         
  172.         /*
  173.          *    Post the error message, and return
  174.          */
  175.  
  176.         PostError(i);
  177.         return NULL;
  178.     }
  179.     
  180.     /*
  181.      *    Step 2:  Allocate and open the window
  182.      */
  183.  
  184.     w = AllocWind();
  185.     GetWMgrPort(&foo);
  186.     r = foo->portRect;
  187.     r.right += openSize.right;
  188.     r.bottom += openSize.bottom;
  189.     r.top = openSize.top;
  190.     r.left = openSize.left;
  191.     InsetRect(&r,4,4);
  192.     NewWindow(w,&r,"\pUntitled",1,8,(char *)-1,CanEject(name),0L);
  193.     step = 2;
  194.     
  195.     /*
  196.      *    Step 3:  Initialize different data structures
  197.      */
  198.  
  199.     w->state = 0;                        /* Directories only */
  200.     w->w.windowKind = WK_PLAN;
  201.     ComputePict(name,w);
  202.  
  203.     CalcScroll(w,&r,&s);
  204.     if (NULL == (w->yScroll = NewControl(w,&s,"",1,0,0,0,16,0L))) Throw(OUTMEM);
  205.     
  206.     t = (GetHandleSize(w->data) / sizeof(struct DirectData)) - 1;
  207.     if (t < 0) t = 0;
  208.     SetCtlMax(w->yScroll,t);
  209.  
  210.     /*
  211.      *    All done.  Return
  212.      */
  213.     
  214.     Uncatch();
  215.     return w;
  216. }
  217.  
  218.  
  219.  
  220.  
  221. /*    ClosePlan
  222.  *
  223.  *    What to do when the 'close' option is selected for a particular plan
  224.  */
  225.  
  226.  
  227. int ClosePlan(w)
  228. struct WindDraw *w;
  229. {
  230.     /*
  231.      *    Dispose of the window and quit
  232.      */
  233.  
  234.     if (!CanEject(w->vRefNum)) return 0;    /* Failure */
  235.     Eject("",w->vRefNum);
  236.     UnmountVol("",w->vRefNum);
  237.     DisposHandle(w->data);
  238.     CloseWindow(w);
  239.     FreeWind(w);
  240.     return 1;                                /* Success */
  241. }
  242.  
  243.  
  244.  
  245. /*    UpdatePlan
  246.  *
  247.  *    This updates the plan (redraws the contents of the window)
  248.  */
  249.  
  250. UpdatePlan(w)
  251. struct WindDraw *w;
  252. {
  253.     DrawGrowIcon(w);
  254.     DrawControls(w);
  255.     DrawPlanWind(w);
  256. }
  257.  
  258.  
  259.  
  260. /*    DrawPlanWind
  261.  *
  262.  *    Actually draw the contents of this drawing window
  263.  */
  264.  
  265. DrawPlanWind(w)
  266. struct WindDraw *w;
  267. {
  268.     int x,y;
  269.     Rect r;
  270.     RgnHandle rgn;
  271.     Rect s;
  272.     long l,i;
  273.     struct DirectData *ptr;
  274.     short ind;
  275.     
  276.     /*
  277.      *    Properly initialize clipping for redrawing the screen
  278.      */
  279.  
  280.     SetPort(w);
  281.     CalcClip(w,&r);
  282.     rgn = NewRgn();
  283.     GetClip(rgn);
  284.     ClipRect(&r);
  285.     
  286.     
  287.     /*
  288.      *    Draw the contents of the screen
  289.      */
  290.  
  291.     HLock(w->data);
  292.     ptr = *(w->data);
  293.     TextFont(4);
  294.     TextSize(9);
  295.     y = GetCtlValue(w->yScroll);
  296.     l = GetHandleSize(w->data) / sizeof(struct DirectData);
  297.     for (i = y, x = 12; i < l; i++, x += 12) {
  298.         for (ind = 0; ind < ptr[i].indent; ind++) {
  299.             MoveTo(ind*12+15,x-10);
  300.             Line(0,12);
  301.         }
  302.         MoveTo(ptr[i].indent*12+10,x);
  303.         DrawString(ptr[i].data);
  304.         if (ptr[i].auxdata[0] != '\0') {
  305.             MoveTo(ptr[i].indent*12+15+StringWidth(ptr[i].data),x);
  306.             LineTo(295,x);
  307.             MoveTo(360 - StringWidth(ptr[i].auxdata),x);
  308.             DrawString(ptr[i].auxdata);
  309.             
  310.             MoveTo(380,x);
  311.             DrawString(ptr[i].auxdata2);
  312.         }
  313.         if (x > r.bottom) break;
  314.     }
  315.     HUnlock(w->data);
  316.         
  317.     
  318.     /*
  319.      *    Reset the clipper properly
  320.      */
  321.  
  322.     SetClip(rgn);
  323.     DisposeRgn(rgn);
  324. }
  325.  
  326.  
  327.  
  328. /*    ActivatePlan
  329.  *
  330.  *    What to do when to activate/deactivate windows
  331.  */
  332.  
  333. ActivatePlan(w,i)
  334. struct WindDraw *w;
  335. int i;
  336. {
  337.     SetPort(w);
  338.     DrawGrowIcon(w);
  339.  
  340.     if (!i) {
  341.         HideControl(w->yScroll);
  342.     } else {
  343.         ShowControl(w->yScroll);
  344.     }
  345. }
  346.  
  347.  
  348. /*    ResizeInitPlan
  349.  *
  350.  *    Do resizing initialization for the plans.  This is so that the object in the
  351.  *    centre of the screen remains in the centre
  352.  */
  353.  
  354. ResizeInitPlan(w)
  355. struct WindDraw *w;
  356. {
  357.  
  358.  
  359.     /*
  360.      *    Handle the scroll bars (they should be invisible during movement)
  361.      */
  362.  
  363.     HideControl(w->yScroll);
  364. }
  365.  
  366.  
  367. /*    ResizePlan
  368.  *
  369.  *    What to do when the window is resized
  370.  */
  371.  
  372. ResizePlan(w)
  373. struct WindDraw *w;
  374. {
  375.     Rect x,y;
  376.  
  377.     SetPort(w);
  378.     
  379.     
  380.     /*
  381.      *    Resize the scroll bars for display again
  382.      */
  383.  
  384.     CalcScroll(w,&x,&y);
  385.     MoveControl(w->yScroll,y.left,y.top);
  386.     SizeControl(w->yScroll,y.right - y.left,y.bottom - y.top);
  387.     ShowControl(w->yScroll);
  388.  
  389.     /*
  390.      *    Prevent the scroll bars from flickering
  391.      */
  392.  
  393.     ValidRect(&x);
  394.     ValidRect(&y);
  395. }
  396.  
  397.  
  398.  
  399.  
  400.  
  401. /*    ScrollPlan
  402.  *
  403.  *    How to scroll the plan window
  404.  */
  405.  
  406. ScrollPlan(w,yo,yn)
  407. struct WindDraw *w;
  408. int yo,yn;
  409. {
  410.     Rect r;
  411.     RgnHandle update;
  412.     
  413.     update = NewRgn();
  414.     SetPort(w);
  415.     CalcClip(w,&r);
  416.     ScrollRect(&r,0,12 * (yo - yn),update);
  417.     DisposeRgn(update);
  418.     DrawPlanWind(w);
  419. }
  420.  
  421.     
  422.  
  423. /*    MyScrollPlan
  424.  *
  425.  *    How scrolling is handled in the end
  426.  */
  427.  
  428. pascal void MyScrollPlan(c,partCode)
  429. ControlHandle c;
  430. short partCode;
  431. {
  432.     short whichDir;
  433.     short delta;
  434.     Rect r;
  435.     int oldval,newval;
  436.     int pin;
  437.  
  438.     r = whichScroll->w.port.portRect;
  439.     whichDir = 0;
  440.  
  441.     switch (partCode) {
  442.         case inUpButton:
  443.             delta = 1;
  444.             break;
  445.         case inPageUp:
  446.             delta = (r.bottom - r.top - 5) / 12;
  447.             break;
  448.         case inDownButton:
  449.             delta = -1;
  450.             break;
  451.         case inPageDown:
  452.             delta = - (r.bottom - r.top - 5) / 12;
  453.             break;
  454.         default:
  455.             delta = 0;
  456.             break;
  457.     }
  458.  
  459.     oldval = GetCtlValue(c);
  460.     newval = oldval - delta;
  461.     if (newval > (pin = GetCtlMax(c))) newval = pin;
  462.     if (newval < (pin = GetCtlMin(c))) newval = pin;
  463.     if (newval == oldval) return;
  464.  
  465.     
  466.     SetCtlValue(c,newval);
  467.     ScrollPlan(whichScroll,oldval,newval);
  468. }
  469.  
  470.  
  471.  
  472. /*    MousePlan
  473.  *
  474.  *    What to do when the mouse goes down in the window
  475.  */
  476.  
  477. MousePlan(w,e,p)
  478. struct WindDraw *w;
  479. EventRecord *e;
  480. Point *p;
  481. {
  482.     int i;
  483.     ControlHandle c;
  484.     int oldval,newval;
  485.  
  486.     i = FindControl(*p,w,&c);
  487.     if (i) {                            /* down in a control:  scroll bar? */
  488.         SetPort(w);
  489.         if (i == inThumb) {
  490.             oldval = GetCtlValue(c);
  491.             TrackControl(c,*p,NULL);
  492.             newval = GetCtlValue(c);
  493.             ScrollPlan(w,oldval,newval);
  494.         } else {
  495.             whichScroll = w;
  496.             TrackControl(c,*p,MyScrollPlan);
  497.         }
  498.     } else {
  499.     }
  500. }
  501.  
  502.  
  503. /*    SetBtn
  504.  *
  505.  *    Set button
  506.  */
  507.  
  508. SetBtn(dlog,i,val)
  509. DialogPtr dlog;
  510. int i;
  511. int val;
  512. {
  513.     short i1;
  514.     Handle i2;
  515.     Rect i3;
  516.  
  517.     GetDItem(dlog,i,&i1,&i2,&i3);
  518.     SetCtlValue(i2,val);
  519. }
  520.  
  521.  
  522. /*    OptionDialog
  523.  *
  524.  *    Set options
  525.  */
  526.  
  527. OptionDialog()
  528. {
  529.     DialogPtr dlog;
  530.     short i1;
  531.     Handle i2;
  532.     Rect i3;
  533.     short x;
  534.     short nv;
  535.     short t;
  536.     short index;
  537.     struct WindDraw *w;
  538.     
  539.     w = (struct WindDraw *)FrontWindow();
  540.     if (w == NULL) return;                            /* not a window to do this to */
  541.     
  542.     nv = w->state;
  543.     dlog = GetNewDialog(OPTIONDLOG,NULL,(char *)-1);
  544.     SetPort(dlog);
  545.     GetDItem(dlog,1,&i1,&i2,&i3);
  546.     PenSize(3,3);
  547.     InsetRect(&i3,-4,-4);
  548.     FrameRoundRect(&i3,16,16);
  549.  
  550.     SetBtn(dlog,4+nv,1);
  551.     for (;;) {
  552.         ModalDialog(NULL,&x);
  553.         switch (x) {
  554.             case 1:
  555.                 DisposDialog(dlog);
  556.                 if (nv != w->state) {
  557.                     w->state = nv;
  558.  
  559.                     SetPort(w);
  560.                     EraseRect(&(w->w.port.portRect));
  561.                     InvalRect(&(w->w.port.portRect));
  562.                     DisposHandle(w->data);
  563.                     ComputePict(w->vRefNum,w);
  564.                     t = (GetHandleSize(w->data) / sizeof(struct DirectData)) - 1;
  565.                     if (t < 0) t = 0;
  566.                     SetCtlMax(w->yScroll,t);
  567.                 }
  568.                 return;
  569.             case 2:
  570.                 DisposDialog(dlog);
  571.                 return;
  572.             case 4:
  573.             case 5:
  574.             case 6:
  575.                 SetBtn(dlog,4+nv,0);
  576.                 nv = x - 4;
  577.                 SetBtn(dlog,4+nv,1);
  578.                 break;
  579.         }
  580.     }
  581. }
  582.